package net.kazed.nextaction.timer;

import java.text.MessageFormat;

import net.kazed.nextaction.R;
import net.kazed.nextaction.database.GtdAndroid;
import net.kazed.nextaction.database.Task;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.widget.RemoteViews;

public class Notifier {

	private static final String CLICK_URI = "clickUri";
   private static final String DESCRIPTION = "text";
   private static final String DURATION_MINUTES = "durationMinutes";
   private static final String START_TIME = "startTime";
   private static final int NOTIFICATION_SERVICE_STARTED = R.string.process_timer_running_title;
   private static final int ALARM_REQUEST_CODE = R.string.process_timer_running_title;

   public static final Uri TOPLEVEL_CONTENT_TIMER_URI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/toplevelTimer");
   public static final String TOPLEVEL_CONTENT_TIMER_ITEM_TYPE = "vnd.android.cursor.item/vnd.nextaction.toplevelTimer";

//   public static final Uri CONTEXT_ROOT_CONTENT_TIMER_URI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/contextRootTimer");
//   public static final String CONTEXT_ROOT_CONTENT_TIMER_ITEM_TYPE = "vnd.android.cursor.item/vnd.nextaction.contextRootTimer";
//
//   public static final Uri CONTEXT_CONTENT_TIMER_URI = Uri.parse("content://" + GtdAndroid.PACKAGE + "/contextTimer");
//   public static final String CONTEXT_CONTENT_TIMER_ITEM_TYPE = "vnd.android.cursor.item/vnd.nextaction.contextTimer";

	private Context context;

	/**
	 * Constructor.
    * @param context Android context.
	 */
	public Notifier(Context context) {
	   this.context = context;
	}

//   /**
//    * Timer started.
//    * @param notificationIntent Intent for use in notification.
//    */
//   @Deprecated
//   public void timerStart(int taskId, String description, final int durationMinutes) {
//      long startTime = System.currentTimeMillis();
//      long nextUpdateTime = startTime + 60000;
//
//      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
//      Uri timerTaskUri = ContentUris.withAppendedId(Task.CONTENT_TIMER_URI, taskId);
//      Intent processIntent = new Intent(Intent.ACTION_VIEW, timerTaskUri);
//      processIntent.putExtra("taskId", taskId);
//      processIntent.putExtra(START_TIME, startTime);
//      processIntent.putExtra(DURATION_MINUTES, durationMinutes);
//      processIntent.putExtra(DESCRIPTION, description);
//      PendingIntent alarmIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, processIntent,
//            PendingIntent.FLAG_UPDATE_CURRENT);
//      alarmManager.set(AlarmManager.RTC_WAKEUP, nextUpdateTime, alarmIntent);
//
//      Resources resources = context.getResources();
//      String titleTemplate = resources.getString(R.string.process_timer_running_title);
//      String title = MessageFormat.format(titleTemplate, 0, durationMinutes);
//      String contentTemplate = resources.getString(R.string.process_timer_running_text);
//      String text = MessageFormat.format(contentTemplate, description);
//      
//      Uri taskUri = ContentUris.withAppendedId(Task.CONTENT_URI, taskId);
//      Intent notificationIntent = new Intent(Intent.ACTION_VIEW, taskUri);
//
//      displayNotification(resources, startTime, notificationIntent, 0, title, text,
//            Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT, 0);
//   }
      
   /**
    * Timer started.
    * @param description Description.
    * @param durationMinutes Duration in minutes.
    */
   public void timerStart(Uri notificationUri, Uri clickUri, String description, final int durationMinutes) {
      long startTime = System.currentTimeMillis();
      long nextUpdateTime = startTime + 60000;

      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      Intent processIntent = new Intent(Intent.ACTION_VIEW, notificationUri);
      processIntent.putExtra(START_TIME, startTime);
      processIntent.putExtra(DURATION_MINUTES, durationMinutes);
      processIntent.putExtra(DESCRIPTION, description);
      processIntent.putExtra(CLICK_URI, clickUri);
      PendingIntent alarmIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, processIntent,
            PendingIntent.FLAG_UPDATE_CURRENT);
      alarmManager.set(AlarmManager.RTC_WAKEUP, nextUpdateTime, alarmIntent);

      Resources resources = context.getResources();
      String titleTemplate = resources.getString(R.string.process_timer_running_title);
      String title = MessageFormat.format(titleTemplate, 0, durationMinutes);
      String contentTemplate = resources.getString(R.string.process_timer_running_text);
      String text = MessageFormat.format(contentTemplate, description);
      
      Intent notificationIntent = new Intent(Intent.ACTION_VIEW, clickUri);

      displayNotification(resources, startTime, notificationIntent, 0, title, text,
            Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT, 0);
   }
      
	/**
	 * Timer started.
    * @param notificationIntent Intent for use in notification.
	 */
	public void timerStart(Intent notificationIntent, final int totalMinutes) {
	   
      Resources resources = context.getResources();
      String titleText = resources.getString(R.string.process_timer_running_title);
      final String contentTemplate = resources.getString(R.string.process_timer_running_text);
      String text = MessageFormat.format(contentTemplate, 0, totalMinutes);

      final int totalSeconds = totalMinutes * 60;
      
      final RemoteViews contentView = new RemoteViews(context.getPackageName(), R.layout.timer_notification);
      contentView.setTextViewText(R.id.timer_status_text, text);
      contentView.setProgressBar(R.id.timer_progress_bar, totalSeconds, 0, false);
      
      final Handler handler = new Handler();

      new Thread(new Runnable() {
          long start;
          long elapsed;
          public void run() {
             start = System.currentTimeMillis();
              while (elapsed < totalSeconds) {
                 try {
                  Thread.sleep(1000);
                 } catch (InterruptedException e) {
                 }
                 elapsed = (System.currentTimeMillis() - start) / 1000;
                  // Update the progress bar
                 handler.post(new Runnable() {
                      public void run() {
                          contentView.setProgressBar(R.id.timer_progress_bar, (int) elapsed, totalSeconds, false);
                          String text = MessageFormat.format(contentTemplate, elapsed, totalMinutes);
                          contentView.setTextViewText(R.id.timer_status_text, text);
                      }
                  });
              }
          }
      }).start();

      displayNotification(resources, contentView, notificationIntent, 0, titleText, text,
            Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT);
	}

   @Deprecated
   public void timerUpdate(int taskId, long startTime, int durationMinutes, String description) {
//      long currentTime = System.currentTimeMillis();
//      long nextUpdateTime = currentTime + 60000;
//      long finishTime = startTime + durationMinutes * 60000;
//      if (nextUpdateTime > finishTime) {
//         nextUpdateTime = finishTime;
//      }
//      int elapsedMinutes = (int) ((currentTime - startTime) / 60000);
//
//      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      Uri timerTaskUri = ContentUris.withAppendedId(Task.CONTENT_TIMER_URI, taskId);
//      Intent processIntent = new Intent(Intent.ACTION_VIEW, timerTaskUri);
//      processIntent.putExtra("taskId", taskId);
//      processIntent.putExtra("startTime", startTime);
//      processIntent.putExtra("durationMinutes", durationMinutes);
//      processIntent.putExtra("text", description);
//      PendingIntent alarmIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, processIntent, 0);
//      alarmManager.set(AlarmManager.RTC_WAKEUP, nextUpdateTime, alarmIntent);
//
//      Resources resources = context.getResources();
//      String titleTemplate = resources.getString(R.string.process_timer_running_title);
//      String title = MessageFormat.format(titleTemplate, elapsedMinutes, durationMinutes);
//      String contentTemplate = resources.getString(R.string.process_timer_running_text);
//      String text = MessageFormat.format(contentTemplate, description);
      
      Uri taskUri = ContentUris.withAppendedId(Task.CONTENT_URI, taskId);
//      Intent notificationIntent = new Intent(Intent.ACTION_VIEW, taskUri);
//
//      displayNotification(resources, startTime, notificationIntent, 0, title, text,
//            Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT, 0);
      
      timerUpdate(timerTaskUri, taskUri, startTime, durationMinutes, description);
   }
   
   public void timerUpdate(Intent intent) {
      Bundle bundle = intent.getExtras();
      long startTime = bundle.getLong(START_TIME);
      int durationMinutes = bundle.getInt(DURATION_MINUTES);
      String description = bundle.getString(DESCRIPTION);
      Uri timerUri = intent.getData();
      Uri clickUri = bundle.getParcelable(CLICK_URI);
      long currentTime = System.currentTimeMillis();
      long nextUpdateTime = currentTime + 60000;
      long finishTime = startTime + durationMinutes * 60000;
      if (nextUpdateTime > finishTime) {
         nextUpdateTime = finishTime;
      }
      int elapsedMinutes = (int) ((currentTime - startTime) / 60000);

      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      Intent processIntent = new Intent(Intent.ACTION_VIEW, timerUri);
      processIntent.putExtra(START_TIME, startTime);
      processIntent.putExtra(DURATION_MINUTES, durationMinutes);
      processIntent.putExtra(DESCRIPTION, description);
      processIntent.putExtra(CLICK_URI, clickUri);
      PendingIntent alarmIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, processIntent, 0);
      alarmManager.set(AlarmManager.RTC_WAKEUP, nextUpdateTime, alarmIntent);

      Resources resources = context.getResources();
      String titleTemplate = resources.getString(R.string.process_timer_running_title);
      String title = MessageFormat.format(titleTemplate, elapsedMinutes, durationMinutes);
      String contentTemplate = resources.getString(R.string.process_timer_running_text);
      String text = MessageFormat.format(contentTemplate, description);
      
      Intent notificationIntent = new Intent(Intent.ACTION_VIEW, clickUri);

      displayNotification(resources, startTime, notificationIntent, 0, title, text,
            Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT, 0);
   }
   
   private void timerUpdate(Uri timerUri, Uri clickUri, long startTime, int durationMinutes, String description) {
      long currentTime = System.currentTimeMillis();
      long nextUpdateTime = currentTime + 60000;
      long finishTime = startTime + durationMinutes * 60000;
      if (nextUpdateTime > finishTime) {
         nextUpdateTime = finishTime;
      }
      int elapsedMinutes = (int) ((currentTime - startTime) / 60000);

      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      Intent processIntent = new Intent(Intent.ACTION_VIEW, timerUri);
      processIntent.putExtra(START_TIME, startTime);
      processIntent.putExtra(DURATION_MINUTES, durationMinutes);
      processIntent.putExtra(DESCRIPTION, description);
      PendingIntent alarmIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, processIntent, 0);
      alarmManager.set(AlarmManager.RTC_WAKEUP, nextUpdateTime, alarmIntent);

      Resources resources = context.getResources();
      String titleTemplate = resources.getString(R.string.process_timer_running_title);
      String title = MessageFormat.format(titleTemplate, elapsedMinutes, durationMinutes);
      String contentTemplate = resources.getString(R.string.process_timer_running_text);
      String text = MessageFormat.format(contentTemplate, description);
      
      Intent notificationIntent = new Intent(Intent.ACTION_VIEW, clickUri);

      displayNotification(resources, startTime, notificationIntent, 0, title, text,
            Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT, 0);
   }
   
//	/**
//	 * Timer stopped.
//    * @param taskId Task ID.
//    * @param description Task description.
//	 */
//   @Deprecated
//	public void timerStop(int taskId, String description) {
//      Uri taskUri = ContentUris.withAppendedId(Task.CONTENT_URI, taskId);
//      Intent notificationIntent = new Intent(Intent.ACTION_VIEW, taskUri);
//      
//      Resources resources = context.getResources();
//      String title = resources.getString(R.string.process_timer_stopped_title);
//      String contentTemplate = resources.getString(R.string.process_timer_stopped_text);
//      String text = MessageFormat.format(contentTemplate, description);
//      
//		NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//		notificationManager.cancel(NOTIFICATION_SERVICE_STARTED);
//      displayNotification(resources, System.currentTimeMillis(), notificationIntent, R.string.process_timer_stopped_ticker, title, text,
//            Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_SHOW_LIGHTS,
//            Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS);
//	}

//   /**
//    * Timer stopped.
//    * @param description Task description.
//    */
//	@Deprecated
//   public void timerStop(Uri notificationUri, String description) {
//      Intent notificationIntent = new Intent(Intent.ACTION_VIEW, notificationUri);
//      
//      Resources resources = context.getResources();
//      String title = resources.getString(R.string.process_timer_stopped_title);
//      String contentTemplate = resources.getString(R.string.process_timer_stopped_text);
//      String text = MessageFormat.format(contentTemplate, description);
//      
//      NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//      notificationManager.cancel(NOTIFICATION_SERVICE_STARTED);
//      displayNotification(resources, System.currentTimeMillis(), notificationIntent, R.string.process_timer_stopped_ticker, title, text,
//            Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_SHOW_LIGHTS,
//            Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS);
//   }

   /**
    * Timer stopped.
    * @param description Task description.
    */
   public void timerStop(Intent intent) {
      Bundle bundle = intent.getExtras();
      String description = bundle.getString(DESCRIPTION);

      Resources resources = context.getResources();
      String title = resources.getString(R.string.process_timer_stopped_title);
      String contentTemplate = resources.getString(R.string.process_timer_stopped_text);
      String text = MessageFormat.format(contentTemplate, description);
      Uri clickUri = bundle.getParcelable(CLICK_URI);
      Intent notificationIntent = new Intent(Intent.ACTION_VIEW, clickUri);

      NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
      notificationManager.cancel(NOTIFICATION_SERVICE_STARTED);
      displayNotification(resources, System.currentTimeMillis(), notificationIntent, R.string.process_timer_stopped_ticker, title, text,
            Notification.FLAG_AUTO_CANCEL | Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_SHOW_LIGHTS,
            Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS);
   }

   /**
    * Cancel running timer.
    * @param taskId Task ID.
    */
   public void timerCancel(Uri notificationUri) {
      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      Intent processIntent = new Intent(Intent.ACTION_VIEW, notificationUri);
      PendingIntent alarmIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, processIntent, 0);
      alarmManager.cancel(alarmIntent);
   }

   /**
    * Cancel running timer.
    * @param taskId Task ID.
    */
   public void timerCancel(int taskId) {
//      AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
      Uri timerTaskUri = ContentUris.withAppendedId(Task.CONTENT_TIMER_URI, taskId);
      timerCancel(timerTaskUri);
//      Intent processIntent = new Intent(Intent.ACTION_VIEW, timerTaskUri);
//      PendingIntent alarmIntent = PendingIntent.getBroadcast(context, ALARM_REQUEST_CODE, processIntent, 0);
//      alarmManager.cancel(alarmIntent);
   }

	private void displayNotification(Resources resources, RemoteViews contentView, Intent notificationIntent, int tickerResource,
	      String titleText, String contentText, int flags) {
      int icon = R.drawable.next_action_icon2;
      String tickerText = null;
      if (tickerResource != 0) {
         tickerText = resources.getString(tickerResource);
      }
      long when = System.currentTimeMillis();

      PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

      Notification notification = new Notification(icon, tickerText, when);
      notification.setLatestEventInfo(context, titleText, contentText, contentIntent);
      notification.flags |= flags;
      if (contentView != null) {
         notification.contentView = contentView;
      }
      
      NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
      notificationManager.notify(NOTIFICATION_SERVICE_STARTED, notification);
	}

   private void displayNotification(Resources resources, long when, Intent notificationIntent, int tickerResource,
         String titleText, String contentText, int flags, int defaults) {
      int icon = R.drawable.next_action_icon2;
      String tickerText = null;
      if (tickerResource != 0) {
         tickerText = resources.getString(tickerResource);
      }

      PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

      Notification notification = new Notification(icon, tickerText, when);
      notification.setLatestEventInfo(context, titleText, contentText, contentIntent);
      notification.flags |= flags;
      notification.defaults = defaults;

      NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
      notificationManager.notify(NOTIFICATION_SERVICE_STARTED, notification);
   }

   public void onReceive(Intent intent) {
      Bundle bundle = intent.getExtras();
      long startTime = bundle.getLong(START_TIME);
      int durationMinutes = bundle.getInt(DURATION_MINUTES);
      long finishTime = startTime + durationMinutes * 60000;
      if (System.currentTimeMillis() > finishTime) {
         timerStop(intent);
      } else {
         timerUpdate(intent);
      }
   }

}
